#!/usr/bin/python3
#
# Copyright (C) 2024, 2025, Cyrus Li (e21920076@126.com). All rights reserved.
#

"""
Format JSON file by deserializing JSON text to a Python Object and serializing
the Python Object again. Note the default indent of formatted JSON file is 4.
"""

import sys
import getopt
import json
import collections

g_debug = False


def debug(s):
    if g_debug:
        print('DEBUG> ' + s)


def new_argv(argv0, rargv):
    argv = []
    argv.append(argv0)
    argv.extend(rargv)
    return argv


def usage(s):
    sys.stderr.write('Usage: %s [-t <indent>] [-d] <[-f <json file>] | txt>\n'
                     % s)
    sys.stderr.write('\t-t: --indent\n')
    sys.stderr.write('\t-d: --debug\n')
    sys.stderr.write('\t-f: --file\n')
    sys.stderr.write('e.g.\n')
    sys.stderr.write('       %s -t 8 -d -f foo.json\n' % s)
    sys.stderr.write('       %s --indent=4 --debug -f foo.json\n' % s)
    sys.stderr.write('       %s \'{"A": 123, "B": "bcd"}\'\n' % s)


def main(argc, argv):
    indent = 4
    json_file = None

    options, rargv = getopt.getopt(argv[1:],
                                   ':f:t:dh',
                                   ['file=', 'indent=', 'debug', 'help'])
    for opt, arg in options:
        if opt in ('-d', '--debug'):
            global g_debug
            g_debug = True
        elif opt in ('-t', '--indent'):
            indent = int(arg)
        elif opt in ('-f', '--file'):
            json_file = arg
        else:
            usage(argv[0])
            return 1

    argv = new_argv(argv[0], rargv)
    argc = len(argv)
    if json_file is None:
        if argc != 2:
            usage(argv[0])
            return 1
        txt = argv[1]
    else:
        with open(json_file, 'r') as f:
            txt = ''.join(f.readlines())

    obj = json.loads(txt, object_pairs_hook=collections.OrderedDict)

    debug(str(type(txt)))
    debug(txt)
    debug(str(type(obj)))
    debug(str(obj))

    out = json.dumps(obj, indent=indent)
    print(out)

    return 0


if __name__ == '__main__':
    sys.exit(main(len(sys.argv), sys.argv))
